<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>循环等待共享锁问题</title>
  <style type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
</head>
<body>
<h2 id="循环等待共享锁问题">循环等待共享锁问题</h2>
<h5 id="日志分析">1、日志分析</h5>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1"><span class="co">#根据日志可以看出两个进程（Process 2027023 和 1942222）形成了循环等待共享锁（ShareLock） 的局面，导致彼此无法继续执行。</span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="ex">Detail</span>: </a>
<a class="sourceLine" id="cb1-3" title="3"><span class="ex">Process</span> 2027023 waits for ShareLock on transaction 239263072<span class="kw">;</span> <span class="ex">blocked</span> by process 1942222.</a>
<a class="sourceLine" id="cb1-4" title="4"><span class="ex">Process</span> 1942222 waits for ShareLock on transaction 239269188<span class="kw">;</span> <span class="ex">blocked</span> by process 2027023.</a></code></pre></div>
<h5 id="死锁的核心原因">2、死锁的核心原因</h5>
<p>死锁的发生需满足四个条件：互斥、持有并等待、不可剥夺、循环等待。此处的关键是循环等待：</p>
<pre><code>进程 2027023 持有事务 239269188 的 ShareLock，同时等待进程 1942222 持有的事务 239263072 的 ShareLock；
进程 1942222 持有事务 239263072 的 ShareLock，同时等待进程 2027023 持有的事务 239269188 的 ShareLock；
两者相互等待对方释放资源，形成闭环，导致死锁。</code></pre>
<h5 id="解决办法">3、解决办法</h5>
<p>数据库通常会自动检测死锁并终止其中一个进程（“牺牲品”）以释放资源。若需手动干预，需优先终止回滚代价更低的进程：</p>
<p>如何选择终止的进程？</p>
<pre><code>看事务执行阶段：若某进程刚启动（执行时间短、修改数据少），回滚代价低，优先终止；
看业务重要性：非核心业务进程优先终止，减少对关键流程的影响；
看锁持有数量：持有锁越少的进程，回滚时释放资源的成本越低。</code></pre>
<p>假设通过日志确认进程 1942222 执行时间更短、修改数据更少，可手动终止：</p>
<pre><code>-- 以SQL Server为例，终止进程（PID为1942222）
KILL 1942222;</code></pre>
<h5 id="长期解决语句分析">4、长期解决，语句分析</h5>
<p>通过查看日志发现，执行的sql为：update t_cas_checkedresult set fbatchno = 0,fcreatorid=1585444342057698305</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb5-1" title="1">没有<span class="ex">WHERE</span>子句 → 会全表更新（锁表中所有记录）</a>
<a class="sourceLine" id="cb5-2" title="2">全表更新的执行流程：</a>
<a class="sourceLine" id="cb5-3" title="3"></a>
<a class="sourceLine" id="cb5-4" title="4">    事务 <span class="ex">A</span> 获取全表的写锁（ROW EXCLUSIVE LOCK）</a>
<a class="sourceLine" id="cb5-5" title="5">    按物理顺序逐行更新记录</a>
<a class="sourceLine" id="cb5-6" title="6">    若此时有其他事务 <span class="ex">B</span> 也在更新同一表（即使是不同行），会因锁冲突导致死锁</a></code></pre></div>
<p>无WHERE条件的全表更新是高风险操作，在生产环境中必须避免。通过明确过滤条件、添加索引和分批处理，可以有效避免死锁，并显著提升更新性能。</p>
</body>
</html>
